package it.webrules.deploymanager.webapp.service.persistence;

import it.webrules.deploymanager.webapp.Constants;
import it.webrules.deploymanager.webapp.auth.DMPrincipal;
import it.webrules.deploymanager.webapp.utils.LogUtils;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Singleton
public class UserStore {

	Logger logger = LoggerFactory.getLogger(LogUtils.formatClassName(this.getClass()));

	private Map<String, DMPrincipal> userdb;
	private File userfile;

	private final StorageSystem storageSystem;

	@SuppressWarnings("unchecked")
	@Inject
	public UserStore(StorageSystem storageSystem) {

		this.storageSystem = storageSystem;

		userfile = storageSystem.getUserFile();
		if (!userfile.exists())
			createNewDBUser();

		try {
			userdb = storageSystem.read();
		} catch (IOException | ClassNotFoundException e) {
			logger.error("Error reading user file,", e);
		}

	}

	public void createNewDBUser() {
		DMPrincipal admin = new DMPrincipal("admin", "admin", Constants.ROLE_ADMIN);
		Map<String, DMPrincipal> userdb = new HashMap<>();
		userdb.put(admin.getName(), admin);

		try {
			storageSystem.save(userdb);
		} catch (IOException e) {
			logger.error("Error creating user file,", e);
		}

	}

	public void createNewUser(String username, String password, String role) {
		DMPrincipal user = new DMPrincipal(username, password, role);
		userdb.put(user.getName(), user);

		try {
			storageSystem.save(userdb);
		} catch (IOException e) {
			logger.error("Error updating user file,", e);
		}
	}

	public DMPrincipal authenticate(String username, String password) {

		if (username == null)
			return null;

		if (userdb.containsKey(username) && userdb.get(username).getPassword().equals(password))
			return userdb.get(username);

		return null;

	}

	public boolean isUserInRole(DMPrincipal principal, String[] rolesRequired) {

		if (rolesRequired.length == 1 && "*".equals(rolesRequired[0]))
			return true;

		for (String role : rolesRequired) {
			if (principal.hasRole(role))
				return true;
		}

		return false;

	}

}
